/*
 *  Copyright (C) 2011 glauco
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.nbpam.windows;

import java.awt.Frame;
import java.util.HashMap;
import java.util.Stack;
import org.balisunrise.application.Application;
import org.balisunrise.common.Transaction;
import org.balisunrise.common.VisualEntity;
import org.balisunrise.application.Window;
import org.balisunrise.common.Editor;
import org.balisunrise.common.EntitySelection;
import org.balisunrise.common.Search;
import org.balisunrise.common.defaults.VEAUtil;

/**
 *
 * @author glauco
 */
public class WindowsManager implements org.balisunrise.application.WindowsManager{

    private Application app;

    private Stack<Window> showedWindows;

    private HashMap<String,Window> instances = new HashMap<String, Window>();

    public Application getApp() {
        if (app == null)
            app = Application.get();
        return app;
    }

    public void setApp(Application app) {
        this.app = app;
    }

    public Stack<Window> getShowedWindows() {
        if(showedWindows == null)
            showedWindows = new Stack<Window>();
        return showedWindows;
    }

    public void setShowedWindows(Stack<Window> showedWindows) {
        this.showedWindows = showedWindows;
    }

    @Override
    public Window showVisualEntity(VisualEntity visualEntity) {

        Window w = createWindow(visualEntity);

        showWindow(w);

        return w;
    }

    @Override
    public void showWindow(Window window) {
        getShowedWindows().push(window);
        window.setVisible(true);
        getShowedWindows().pop();
    }

    @Override
    public Window getActiveWindow() {

        if (getShowedWindows().empty())
            return null;

        return getShowedWindows().peek();
    }

    /**
     * É criado uma Window para exibição da representação visual.<br>
     * @param visualEntity VisualEntity a ser exibida.
     * @return A Window criada.
     */
    @Override
    public Window createWindow(VisualEntity ve){

        Window topWindow = VEAUtil.getWindow(ve);
        if(topWindow == null)
            return createTopWindow(ve);
        else
            return criateDialogWindow(ve);
    }

    /**
     * Cria uma Window TopComponent.
     * @param ve Entidade Visual.
     * @return uma Window do tipo Top Component.
     */
    private Window createTopWindow(VisualEntity ve){

        if (instances.containsKey(ve.getName())){
            return instances.get(ve.getName());
        }

        Window v;
        switch (ve.getVisualEntityType()) {
            case TRANSACTION:
                v = new org.balisunrise.nbpam.windows.Window(
                        getApp(),
                        new TransactionTopComponent((Transaction) ve));
                break;
            case SEARCH:
                v = new org.balisunrise.nbpam.windows.Window(
                        getApp(),
                        new SearchTopComponent((Search) ve));
                break;
            case EDITOR:
                v = new org.balisunrise.nbpam.windows.Window(
                        getApp(),
                        new EditorTopComponent((Editor) ve));
                break;
            default:
                throw new AssertionError();
        }

        instances.put(ve.getName(), v);
        ve.setOwner(v);
        v.setOwner(Application.get());
        return v;
    }

    /**
     * Cria uma Window JDialog.
     * @param ve Entidade Visual.
     * @return uma Window do tipo JDialog.
     */
    private Window criateDialogWindow(VisualEntity ve){

        Window w;
        switch (ve.getVisualEntityType()) {
            case SEARCH:
                w = new org.balisunrise.nbpam.windows.DialogWindow(
                        getApp(),
                        new SearchDialog(
                            (Frame) app.getVisualRepresentation(),
                            (Search) ve));
                break;
            case ENTITY_SELECTION:
                w = new org.balisunrise.nbpam.windows.DialogWindow(
                        getApp(),
                        new SelectionDialog(
                            (Frame) app.getVisualRepresentation(),
                            (EntitySelection) ve));
                break;
            case EDITOR:
                w = new org.balisunrise.nbpam.windows.DialogWindow(
                        getApp(),
                        new EditorDialog(
                            (Frame) getApp().getVisualRepresentation(),
                            (Editor) ve));
            default:
                throw new AssertionError();
        }

        ve.setOwner(w);
        w.setOwner(ve);
        return w;
    }

    /**
     * Retorna as instâncias de Windows abertas, visiveis.
     */
    @Override
    public Window[] getWindows() {
        // TODO: verificar se as janelas estão abertas.
        return instances.values().toArray(new Window[0]);
    }
}
